#pragma once
#include <memory>
#include <string>
#include <any>
#include "../../utils/common_ptr.h"
#include "../../utils/BOOL.h"
class Object
{
public:
  std::any any_data_;
  enum ParamType
  {
    CLASS,
    STRING,
    INT,
    BOOL,
    NULL_,
    LONG,
    LONGLONG,
    DOUBLE,
    LISTLISTOBJ,
    LISTOBJ,
    LISTSTR,
    CHAR,
    SHORT,
    FLOAT,
    WCHAR,
    WSTRING,
    SQLSELECTORDERBYITEM_LIST_PTR,
  };
  union Private_
  {
    char argC;
    char *argS;
    int argI;
    bool argB;
    long argL;
    long long argLL;
    double argD;
    short argShort;
    float argF;
    wchar_t argWC;
    wchar_t* argWS;
  } Private;

  std::shared_ptr<std::list<Object_list_ptr>> argLLO;
  Object_list_ptr argLO;
  string_list_ptr argLS;
  SQLSelectOrderByItem_list_ptr argSQLSelectOrderByItem_list_ptr;

  Object(SQLSelectOrderByItem_list_ptr par)
  {
    this->argSQLSelectOrderByItem_list_ptr = argSQLSelectOrderByItem_list_ptr;
    this->paramType = SQLSELECTORDERBYITEM_LIST_PTR;
  }
  SQLSelectOrderByItem_list_ptr getSQLSelectOrderByItem_list_ptr() const
  {
    return this->argSQLSelectOrderByItem_list_ptr;
  }

  Object(string_list_ptr par)
  {
    this->argLS = par;
    this->paramType = LISTSTR;
  }
  string_list_ptr getLS() const
  {
    return this->argLS;
  }

  Object(const std::wstring &par)
  {
    const wchar_t *ptr = par.c_str();
    this->Private.argWS = (wchar_t *)ptr;
    this->paramType = WSTRING;
  }
  std::wstring getWString() const
  {
    return this->Private.argWS;
  }

  Object(wchar_t &par)
  {
    this->Private.argWC = par;
    this->paramType = WCHAR;
  }
  wchar_t getWChar() const
  {
    return this->Private.argWC;
  }

  Object(float &par)
  {
    this->Private.argF = par;
    this->paramType = FLOAT;
  }
  float getFloat() const
  {
    return this->Private.argF;
  }

  Object(short &par)
  {
    this->Private.argShort = par;
    this->paramType = SHORT;
  }
  short getShort() const
  {
    return this->Private.argShort;
  }

  Object(char &par)
  {
    this->Private.argC = par;
    this->paramType = CHAR;
  }
  char getC() const
  {
    return this->Private.argC;
  }

  Object(Object_list_ptr par)
  {
    this->argLO = par;
    this->paramType = LISTOBJ;
  }
  Object_list_ptr getLO() const
  {
    return this->argLO;
  }

  Object(std::shared_ptr<std::list<Object_list_ptr>> par)
  {
    this->argLLO = par;
    this->paramType = LISTLISTOBJ;
  }
  std::shared_ptr<std::list<Object_list_ptr>> getLLO() const
  {
    return this->argLLO;
  }

  Object(const long long &par)
  {
    this->Private.argLL = par;
    this->paramType = LONGLONG;
  }
  long long getLongLong() const
  {
    return this->Private.argLL;
  }

  Object(const double &par)
  {
    this->Private.argD = par;
    this->paramType = DOUBLE;
  }
  double getDouble() const
  {
    return this->Private.argD;
  }

  Object(const long &par)
  {
    this->Private.argL = par;
    this->paramType = LONG;
  }
  long getLong() const
  {
    return this->Private.argL;
  }

  Object()
  {
    this->paramType = CLASS;
  }

  Object(const std::string &par)
  {
    const char *ptr = par.c_str();
    this->Private.argS = (char *)ptr;
    this->paramType = STRING;
  }

  Object(const int &par)
  {
    this->Private.argI = par;
    this->paramType = INT;
  }

  Object(const bool &par)
  {
    this->Private.argB = par;
    this->paramType = BOOL;
  }

  int getInt() const
  {
    return this->Private.argI;
  }

  std::string getString() const
  {
    return this->Private.argS;
  }

  bool getBool() const
  {
    return this->Private.argB;
  }

  const ParamType getType() const
  {
    return this->paramType;
  }

  void setNull()
  {
    this->paramType = NULL_;
  }

  virtual string_ptr toString()
  {
    return make_string_ptr("");
  }

  virtual int hashCode() { return typeid(*this).hash_code(); };

  virtual bool equals(Object_ptr obj)
  {
    if (this == obj.get())
    {
      return true;
    }
    else
    {
      return false;
    }
  }
  virtual bool equals(Object *obj)
  {
    if (this == obj)
    {
      return true;
    }
    else
    {
      return false;
    }
  }

  GETCALSS(Object);

private:
  ParamType paramType;
};
